package cn.etynit.basic.service.impl;

import cn.etynit.basic.config.BussinessException;
import cn.etynit.basic.constant.BaseConstant;
import cn.etynit.basic.dto.EmailRegisterForm;
import cn.etynit.basic.dto.PhoneSmsCodeDto;
import cn.etynit.basic.service.IverifyCodeService;
import cn.etynit.basic.util.StrUtils;
import cn.etynit.basic.util.VerifyCodeUtils;
import cn.etynit.user.domain.User;
import cn.etynit.user.mapper.LogininfoMapper;
import cn.etynit.user.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;
import javax.mail.MessagingException;
import java.util.concurrent.TimeUnit;
import java.util.regex.Pattern;

@Service
@Slf4j
public class verifyCodeServiceImpl implements IverifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LogininfoMapper logininfoMapper;

    @Autowired
    private JavaMailSender sender;

    /**
     * 获取图形验证码
     * @param uuidKey
     * @return
     */
    @Override
    public String getImageCode(String uuidKey) {
        // 生成随机数
        String randomCode = StrUtils.getComplexRandomString(4);
        // 存入到reids 有效时间3分钟
        redisTemplate.opsForValue().set(uuidKey,randomCode,3, TimeUnit.MINUTES);
        // 生成图形验证码返回给前端
        return VerifyCodeUtils.VerifyCode(100,35,randomCode);
    }

    /**
     * 手機註冊和微信手機號綁定驗證方法
     * @param dto
     */
    @Override
    public void smsCode(PhoneSmsCodeDto dto) {
        // 手機註冊驗證
        if ("register".equals(dto.getType())){
            // 驗證手機號
            this.verifyPhone(dto);
            // 驗證驗證圖片驗證碼
            this.verifyImgageCode(dto);
            // 两次发送短信间隔是否大于60s
            this.sendSmsCode(String.format(BaseConstant.VerfityCodeCons.BINDER_SMSCODE_PHONE,dto.getPhone()));
        }else if("binder".equals(dto.getType())){
            // 微信手機號綁定驗證
            this.sendSmsCode(String.format(BaseConstant.VerfityCodeCons.BINDER_SMSCODE_PHONE,dto.getPhone()));
        }
    }

    /**
     * 驗證手機號碼
     * @param dto
     */
    public void  verifyPhone(PhoneSmsCodeDto dto){
        // 验证参数是否为空
        // 验证手机号格式
        if (dto.getPhone().length() != 11) {
            throw new BussinessException("请输入正确的手机号！");
        } else {
            String regex = "^((13[0-9])|(15[^4])|(18[0,2,3,5-9])|(17[0-8])|(147))\\d{8}$";
            boolean isMatch = Pattern.compile(regex).matcher(dto.getPhone()).matches();
            if (!isMatch) {
                throw new BussinessException("请输入正确的手机号！");
            }
        }
    }


    /**
     * 獲取手機驗證碼方法
     * @param rediskey
     */
    private void sendSmsCode(String rediskey) {
        // 两次发送短信间隔是否大于60s
        // redis中 key：register:smscode:phone  value：验证码:时间戳
        String redisSmsCode = (String) redisTemplate.opsForValue().get(rediskey);
        String smsCode = "";
        if(StringUtils.isNotBlank(redisSmsCode)){
            String[] split = redisSmsCode.split(":");
            smsCode = split[0];
            // 当前时间
            long newTime = System.currentTimeMillis();
            // reids中的时间
            long oldTime = Long.valueOf(split[1]);
            if(newTime - oldTime < 60 * 1000){
                throw new BussinessException("获取验证码太快了，请稍后重试");
            }
        } else {
                // 生成验证码（英文+数字）
                //smsCode = StrUtils.getComplexRandomString(4);
                // 生成验证码（纯数字）
                smsCode = StrUtils.getRandomString(4);
            }
        log.info("验证码为：{}",smsCode);
        String redisValue = smsCode + ":" + System.currentTimeMillis();
        // 存入到reids
        redisTemplate.opsForValue().set(rediskey,redisValue,5,TimeUnit.MINUTES);
        // 发送短信
//        SendSmsUtil.send(dto.getPhone(),"你好：你的验证码为："+smsCode+"，5分钟内有效！");
        // 是否需要重置验证码
    }


    /**
     * 圖形驗證碼方法
     * @param dto
     */
    private void verifyImgageCode(PhoneSmsCodeDto dto) {
        // 图形验证码是否正确
        String imageCode = (String) redisTemplate.opsForValue().get(dto.getImageCodeKey());
        if(StringUtils.isBlank(imageCode) || !imageCode.equalsIgnoreCase(dto.getImageCodeValue())){
            throw new BussinessException("图形验证码错误！");
        }
        // 当前手机号是否已经注册了
        User user = userMapper.findByPhone(dto.getPhone());
        if(null != user){
            throw new BussinessException("该手机号已注册！");
        }
    }


    /**
     * 邮箱注册
     * @param edto
     * @throws MessagingException
     */
    @Override
    public void email(EmailRegisterForm edto) throws MessagingException {
        String imageCode = (String) redisTemplate.opsForValue().get(edto.getImageCodeKey());
        if(StringUtils.isBlank(imageCode) || !imageCode.equalsIgnoreCase(edto.getImageCodeValue())){
            throw new BussinessException("图形验证码错误！");
        }
        // 当前手机号是否已经注册了
        User user = userMapper.findByEmail(edto.getEmail());
        if(null != user){
            throw new BussinessException("该邮箱已注册！");
        }
        // redis中 key：register:smscode:email  value：验证码:时间戳
        String redisSmsCode = (String) redisTemplate.opsForValue().get(String.format(BaseConstant.VerfityCodeCons.REGISTER_SMSCODE_EMAIL, edto.getEmail()));
        String smsCode = "";
        if(StringUtils.isNotBlank(redisSmsCode)){
//            Long expire = redisTemplate.getExpire(String.format(BaseConstant.VerfityCodeCons.REGISTER_SMSCODE_PHONE, dto.getPhone()), TimeUnit.MINUTES);
//            if (expire >= 4){
//                throw new BussinessException("滚！");
//            }
            // 不为空才做 60s校验  redisSmsCode 存的是 验证码:时间戳
            String[] split = redisSmsCode.split(":");
            smsCode = split[0];
            // 当前时间
            long newTime = System.currentTimeMillis();
            // reids中的时间
            long oldTime = Long.valueOf(split[1]);
            if(newTime - oldTime < 60 * 1000){
                throw new BussinessException("获取验证码太快了，请稍后重试");
            }
        } else {
            // 生成验证码
            smsCode = StrUtils.getComplexRandomString(4);
        }
        log.info("验证码为：{}",smsCode);
        String redisValue = smsCode + ":" + System.currentTimeMillis();
        // 存入到reids
        redisTemplate.opsForValue().set(String.format(BaseConstant.VerfityCodeCons.REGISTER_SMSCODE_EMAIL,
                edto.getEmail()),redisValue,5,TimeUnit.MINUTES);
        // 发送邮件
        // 1.创建复杂邮件对象
//        MimeMessage mimeMessage = sender.createMimeMessage();
//        // 2.发送复杂邮件的工具类
//        MimeMessageHelper helper = new MimeMessageHelper(mimeMessage,true,"utf-8");
//        helper.setFrom("wang155775@qq.com");
//        helper.setSubject("宠物之家入驻通知");
//        // 3.设置文本内容，第二个参数 true 代表是否是一个html内容
//        helper.setText("<h1>您好，您的注册验证码为</h1>"+smsCode ,true);
//        // 4.添加附件
//        //helper.addAttachment("她的照片",new File("C:\\Users\\王亦晨\\Desktop\\study\\89383762_680006909411708_95259810529804288_o.jpg"));
//        // 5.设置收件人
//        helper.setTo(edto.getEmail());
//        // 6.发送邮件
//        sender.send(mimeMessage);

    }
}
